package com.blb.shiro;

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.blb.entity.User;
import com.blb.entity.UserExample;
import com.blb.mapper.UserMapper;

public class MyRealm extends AuthorizingRealm {

	@Autowired
	private UserMapper userMapper;
	
	/**
	 * 授权
	 * 根据用户名获取用户的角色和权限信息
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		User user = (User) principals.getPrimaryPrincipal();
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		
		//获取角色集合
		List<String> roles = userMapper.getRoles(user.getUsername());
		//获取权限标识符集合
		List<String> permissions = userMapper.getStringPermission(roles);
		
		simpleAuthorizationInfo.addRoles(roles);
		simpleAuthorizationInfo.addStringPermissions(permissions);
		
		simpleAuthorizationInfo.addRole("user");				//角色
		simpleAuthorizationInfo.addStringPermission("user");	//权限标识符
		
		return simpleAuthorizationInfo;
	}

	/**
	 * 登录认证
	 * 1、从令牌中获取用户名
	 * 2、根据用户名查询数据库
	 * 
	 * 
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		//从令牌中获取用户名
		String username = (String) token.getPrincipal();

		//根据用户名查询数据库
		UserExample userExample = new UserExample();
		userExample.createCriteria().andUsernameEqualTo(username);
		List<User> list = userMapper.selectByExample(userExample);
		
		if (list.isEmpty()) {
			return null;		//表示用户名不存在
		}
		User user = list.get(0);
		if (user.getStatus()==-1) {
			throw new LockedAccountException();	//表示账号被锁定
		}
		
		//1、用户信息；2、数据库密码；3、getName()
		return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()) ,getName());
	}
}
